﻿// <copyright file="VfsMappingListEntry.cs" company="Sinclair Community College">
// Copyright 2010 Sinclair Community College
// </copyright>
// <originalAuthor>Patrick S. Seymour (patrick.seymour@gmail.com)</originalAuthor>

namespace SinclairCC.AppV
{
    using System;

    /// <summary>
    /// This class represents an entry in the VFS mapping section (section 0x00)
    /// of the CP file.
    /// </summary>
    internal class VfsMappingListEntry
    {
        /// <summary>
        /// The size of the entry block in total number of bytes.
        /// </summary>
        private int entrySize;

        /// <summary>
        /// The size of the entry block header (i.e., all the data before path strings).
        /// </summary>
        /// <remarks>
        /// This size is fixed at 0x00000020 ({0x20, 0x00, 0x00, 0x00}).
        /// </remarks>
        private int entryBlockHeaderSize;

        /// <summary>
        /// The size of the virtualized ("target") path string in bytes.
        /// </summary>
        private int virtualizedPathSize;

        /// <summary>
        /// The relative byte offset to the virtualized ("target") path string inside
        /// mapping entry block.
        /// </summary>
        /// <remarks>
        /// The offset is relative to the beginning of the entry block header.
        /// </remarks>
        private int virtualizedPathOffset;

        /// <summary>
        /// The size of the physical ("source") path string in bytes.
        /// </summary>
        private int packagePathSize;

        /// <summary>
        /// The relative byte offset to the physical ("source") path string
        /// inside mapping entry block.
        /// </summary>
        /// <remarks>
        /// The offset is relative to the beginning of the entry block header.
        /// </remarks>
        private int packagePathOffset;

        /// <summary>
        /// Indicates the presence of virtualized and package paths.
        /// </summary>
        private PathAttribute pathFlags;

        /// <summary>
        /// Indicates the type of virtualized path.
        /// </summary>
        private VirtualizedPathAttributes attributes;

        /// <summary>
        /// The source path that is to be mapped to a target path.
        /// </summary>
        private string sourcePath;

        /// <summary>
        /// The path to which the source path will be mapped on the client.
        /// </summary>
        private string targetPath;

        /// <summary>
        /// Initializes a new instance of the VfsMappingListEntry class.
        /// </summary>
        /// <param name="dataStream">
        /// A MemoryStream containing the raw data for the VFS mapping entry.
        /// </param>
        public VfsMappingListEntry(System.IO.MemoryStream dataStream)
        {
            this.sourcePath = string.Empty;
            this.targetPath = string.Empty;
            this.ReadSection(dataStream);
        }

        /// <summary>
        /// Gets the source path that will be mapped to the target path on the client.
        /// </summary>
        public string SourcePath
        {
            get { return this.sourcePath; }
        }

        /// <summary>
        /// Gets the target path to which the source path will be mapped on the client.
        /// </summary>
        public string TargetPath
        {
            get { return this.targetPath; }
        }

        /// <summary>
        /// Gets a value indicating the presence of virtualized and package paths.
        /// </summary>
        public PathAttribute Flags
        {
            get { return this.pathFlags; }
        }

        /// <summary>
        /// Gets the type of virtualized path.
        /// </summary>
        public VirtualizedPathAttributes Attributes
        {
            get { return this.attributes; }
        }

        /// <summary>
        /// Reads the actual data for this section from the file.
        /// </summary>
        /// <param name="dataStream">
        /// A MemoryStream containing the raw data for the VFS mapping entry.
        /// </param>
        private void ReadSection(System.IO.MemoryStream dataStream)
        {
            System.IO.BinaryReader streamReader = new System.IO.BinaryReader(dataStream);

            this.entrySize = streamReader.ReadInt32();
            this.entryBlockHeaderSize = streamReader.ReadInt32();
            this.virtualizedPathSize = streamReader.ReadInt32();
            this.virtualizedPathOffset = streamReader.ReadInt32();
            this.packagePathSize = streamReader.ReadInt32();
            this.packagePathOffset = streamReader.ReadInt32();
            this.pathFlags = (PathAttribute)streamReader.ReadInt32();
            this.attributes = (VirtualizedPathAttributes)streamReader.ReadInt32();
            this.sourcePath = System.Text.Encoding.Unicode.GetString(streamReader.ReadBytes(this.packagePathSize));
            this.targetPath = System.Text.Encoding.Unicode.GetString(streamReader.ReadBytes(this.virtualizedPathSize));
        }
    }
}
